package model

import (
	"cron_table_admin/global"
	"encoding/json"
	"time"

	"github.com/go-resty/resty/v2"
	"go.uber.org/zap"
)

type Cron struct {
	Id             int64     `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT"`
	Name           string    `json:"name" gorm:"column:name"`
	Classification string    `json:"classification" gorm:"column:classification"`
	Status         int       `json:"status" gorm:"column:status"`
	ReqType        string    `json:"req_type" gorm:"column:req_type"`
	Expr           string    `json:"expr" gorm:"column:expr"`
	Desc           string    `json:"desc" gorm:"column:desc"`
	Url            string    `json:"url" gorm:"column:url"`
	Param          string    `json:"param" gorm:"column:param"`
	Method         string    `json:"method" gorm:"column:method"`
	NextTime       string    `json:"next_time" gorm:"column:next_time"`
	LastTime       string    `json:"last_time" gorm:"column:last_time"`
	CreatedAt      time.Time `json:"created_at" gorm:"column:created_at"`
	UpdatedAt      time.Time `json:"updated_at" gorm:"column:updated_at"`
}

func (c Cron) TableName() string {
	return "cron"
}

func (c Cron) ExecuteFunc() {
	client := resty.New()
	bodyMap := make(map[string]string)
	if c.Param != "" {
		err := json.Unmarshal([]byte(c.Param), &bodyMap)
		if err != nil {
			global.LOGGER.Error("ExecuteFunc error", zap.Any("Param Unmarshal error: ", err))
		}
	}
	request := client.R().
		EnableTrace(). // You should turn on `EnableTrace`, otherwise the curl command will not contain the body
		SetBody(bodyMap)
	response, err := request.Execute(c.Method, c.Url)
	if err != nil {
		global.LOGGER.Error("request.Execute error", zap.Any("err:", err))
	}
	global.LOGGER.Info("request.Execute", zap.Any("StatusCode:", response.StatusCode()))
}

func (c Cron) Execute() {
	switch c.ReqType {
	case "http":
		c.ExecuteFunc()
	default:
		global.LOGGER.Error("Execute error", zap.Any("Type:", c.ReqType))
	}
}

func (c Cron) Start() {
	id, err := global.CronTable.AddFunc(c.Expr, func() {
		c.ExecuteFunc()
	})
	if err != nil {
		global.LOGGER.Error("Execute error", zap.Any("err:", err))
		return
	}
	global.SetCronMappingId(c.Id, id)
}

func (c Cron) Stop() {
	global.CronTable.Remove(global.GetCronMappingId(c.Id))
	global.DelCronMappingId(c.Id)
}
